<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <!-- $Id: concurrency.html,v 1.6 2005/09/29 14:52:29 andy_seaborne Exp $ -->
  <title>Concurrency in Jena</title>
  <link href="../styles/doc.css" rel="stylesheet" type="text/css">
  
<style>
.box { margin-left : 5% ;
       margin-right : 7% ;
       border: 1px solid ;
       background-color: #F0F0F0; 
       padding: 10;
       page-break-inside: avoid ;
       }
  </style>
</head>
<body>

<h1>Concurrent access to Models</h1>

<p>Applications need to be aware of the concurrency issues in access Jena 
models.&nbsp; API operations are not thread safe by default. Thread safety would 
simple ensure that the model datastructures remained intact but would not give 
an application consistent access to the RDF graph.&nbsp; It would also limit the 
throughput of multithreaded applications on multiprocessor machines where true 
concurrency can lead to a reduction in response time.</p>

<p>For example, supposed an application wishes to read the name and age of a 
person from model.&nbsp; This takes two API calls.&nbsp; It is more convenient 
to be able to read that information in a consistent fashion, knowing that the 
access to the second piece of information is not being done after some model 
change has occurred.</p>

<p>Special care is needed with iterators.&nbsp; In general, Jena's iterators do
<i>not</i> take a copy to enable safe use in the presence of concurrent update.&nbsp; 
A multithreaded application needs to be aware of these issues and correctly use 
the mechanisms that Jena provides (or manage its own concurrency itself).&nbsp; 
While not zero, the application burden is not high.</p>

<p>There are two main cases:</p>

<ul>
  <li>Multiple threads in the same JVM.</li>
  <li>Multiple applications accessing the same persistent model (typically, a 
  database).</li>
</ul>

<p>Transactions are provided by database-backed models: see the
<a href="../DB/index.html">database documentation</a> and the
<a href="../javadoc/com/hp/hpl/jena/rdf/model/Model.html#supportsTransactions()">Model interface to 
transactions</a>.</p>

<p>This note describes the support for same-JVM, multithreaded applications.</p>

<h2>Locks</h2>
<p>Locks provide critical section support for managing the interactions of 
multiple threads in the same JVM.&nbsp; Jena provides 
multiple-reader/single-writer concurrency support (MRSW).</p>
<p>The pattern general is:</p>

<pre class="box">Model model = . . . ;
model.enterCriticalSection(Lock.READ) ;  // or Lock.WRITE
try {
    ... perform actions on the model ...
    ... obey contract - no update operations if a read lock
} finally {
    model.leaveCriticalSection() ;
}</pre>
<p>Applications are expected to obey the lock contract, that is, they must not 
do update operations if they have a read lock as there can be other application 
threads reading the model concurrently.</p>

<h2>Iterators</h2>

<p>Care must be taken with iterators: unless otherwise stated, all iterators 
must be assumed to be iterating over the datastructures in the model or graph 
implementation itself.&nbsp; It is not possible to safely pass these out of
criticial sections.</p>

<h2>SPARQL Query</h2>
<p>SPARQL query results are iterators and no different from other iterators in 
Jena for concurrency purposes.&nbsp; The default query engine does not give 
thread safety and the normal requirements on an application to ensure MRSW 
access in the presence of iterators applies.&nbsp; Note that Jena's query 
mechanism is itself multithreaded. If the application is single threaded, no 
extra work is necessary.&nbsp; If the application is multithreaded, queries 
should be executed with a read lock.</p>
<p>Outline:</p>

<pre class="box">
  Model model = ... ;
  String queryString = " .... " ;
  Query query = QueryFactory.create(queryString) ;
  model.<b>enterCriticalSection</b>(<b>Lock.READ</b>) ;
  try {
    QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
    ResultSet results = qexec.execSelect() ;
   try {
      for ( ; results.hasNext() ; )
      {
          QuerySolution soln = results.nextSolution() ;
          RDFNode x = soln.get(&quot;..var name..&quot;) ;
      }
    } finally { qexec.close() ; }
  } finally { model.<b>leaveCriticalSection</b>() ; }</pre>
<p>Updates to the model should not be performed inside the read-only section.&nbsp; 
For database-backed models, the application can use a transaction.&nbsp; For 
in-memory models, the application should collect the changes together during the 
query processing then making all the changes holding a write lock.</p>
<p>Jena Locks do not provide lock promotion - an application can not start 
a &quot;write&quot; critical section while holding a &quot;read&quot; lock because this can lead to 
deadlock.</p>
<h2>Compatibility</h2>
<p>The actually interface is called <code>Lock</code> and has implementations 
including <code>LockMRSW</code>.</p>
<p>For compatibility with previous versions of Jena, there is a class <code>
ModelLock</code>.</p>
<p>&nbsp;</p>

</body>
</html>
